/**
 * Project Untitled
 */


#include "../../include/tcpServer/ThreadPool.h"

/**
 * ThreadPool implementation
 */


/**
 * @param threadNumber
 * @param queueSize
 */
ThreadPool::ThreadPool(size_t threadNumber, size_t queueSize)
    :_threadNumber(threadNumber)
    ,_taskQueue(queueSize)
     ,_exit(false)
{}

/**
 * @param task
 * @return void
 */
void ThreadPool::addTask(Task && task) {
    if(!_exit && task){
        _taskQueue.push(std::move(task)); // 往任务队列里面插入元素。 
    }
    return;
}

/**
 * @return void
 */
void ThreadPool::start() {
    for(size_t i = 0; i < _threadNumber; ++i){
        std::unique_ptr<Thread> upth(new Thread(std::bind(&ThreadPool::doTask, this, std::placeholders::_1), i)); // 初始回调函数到线程的数据成员。以待合适的时候调用。 doTask 是从任务队列中取出任务。 
        _threadPool.push_back(std::move(upth));
    }
    for(auto &it : _threadPool){
        it->create(); // 每个线程都去互斥地执行任务dotask ， 如果任务队列没有任务那么线程就去等待。 
    }
    return;
}

/**
 * @return void
 */
void ThreadPool::shutdown() {
    _exit = true;
    while(!_taskQueue.isEmpty()){
        sleep(1);
    }

    _taskQueue.wakeUpAll();  

    for(auto &it : _threadPool){
        it->join();
    }
    return;
}




/**
 * @return void
 */
void ThreadPool::doTask(int tNum) { // 做任务，pop出元素。 
    while(!_exit || !_taskQueue.isEmpty()){
        Task task = _taskQueue.pop();   // 先pop出任务。
        if(task) task(tNum); // 
        else break;
    }
    return;
}
